# 词库模块，读、写和转换词库的中间数据结构
import re

from base import *

# ^\S+\t[a-z0-9]+([ ]?[a-z0-9]+)*(\t\d+)?$
_reg = '^\\S+\\t[a-z0-9]+([ ]?[a-z0-9]+)*(\\t\\d+)?$'
_item_reg = re.compile(_reg)


class RimeDictItem(object):
    """
    rime 格式的词条
    """

    def __init__(self, text: str, code: str, weight=0):
        self.text = text
        self.code = code
        self.weight = weight

    def __str__(self) -> str:
        return '{}\t{}\t{}'.format(self.text, self.code, self.weight)


class RimeDict(object):
    """
    词典
    """

    def __init__(self, dict_file):
        self.dictFile = dict_file
        self._loaded = False
        self._items = []  # 词典中包含的词条
        self._textToIndex = {}  # text -> index mapping

    def load(self, skip_head=False):
        if self._loaded:
            return
        file = open_file_as_utf8(self.dictFile)
        index = 0
        skipHead = skip_head
        for line in file:
            if line.startswith("#"):
                continue
            if skipHead:
                if line.startswith('...'):
                    skipHead = False  # 内容开始了
                    continue
                continue  # 跳过文件头
            if not _item_reg.match(line):
                print("<{}> not match reg: {}".format(line, _reg))
                continue
            segments = line.split('\t', maxsplit=3)
            text = segments[0].strip()
            code = segments[1].strip()
            weight = int(segments[2].strip()) if len(segments) > 2 else 0
            item = RimeDictItem(text, code, weight)
            self._items.append(item)
            if text not in self._textToIndex:
                self._textToIndex[text] = index
            index += 1
        file.close()
        self._loaded = True

    @property
    def loaded(self):
        return self._loaded

    @property
    def items(self):
        return self._items

    def hasText(self, text):
        return text in self._textToIndex

    def getItem(self, text):
        if self.hasText(text):
            return self._items[self._textToIndex.get(text)]
        return None
